/*
 * @Author: 我想吃余 483766615@qq.com
 * @Date: 2025-11-15 21:23:29
 * @LastEditors: 我想吃余 483766615@qq.com
 * @LastEditTime: 2025-11-16 15:03:52
 * @FilePath: /code/oscode/thread_pool/ThreadPool.hpp
 * @Description: 这In置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once

#include <iostream>
#include <pthread.h>
#include <vector>
#include <queue>
#include <string>
#include "Thread.hpp"
#include "task.hpp"

#define NUM 10

template<class T>
class threadpool
{
private:
     void Lock()
     {
          pthread_mutex_lock(&_mutex);
     }
     void UnLock()
     {
          pthread_mutex_unlock(&_mutex);
     }
     void WaitUp()
     {
          pthread_cond_signal(&_cond);
     }
     void ThreadSleep()
     {
          pthread_cond_wait(&_cond, &_mutex);
     }
     bool IsEmpty()
     {
          return _taskqueue.empty();
     }
     std::string GetName(pthread_t tid)
     {
          for(auto &t : _threads)
          {
               if(t.GetTid() == tid)
                    return t.GetName();
          }
          return "None!";
     }
public:
     threadpool(int num = NUM)
     :_num(num)
     {
          pthread_mutex_init(&_mutex, nullptr);
          pthread_cond_init(&_cond, nullptr);
     }

     // 实例化线程池的线程对象（注意此时线程还并未真正创建，需要start启动）
     void Init()
     {
          for(int i = 0; i < _num; ++i)
               _threads.push_back(Thread(i, HandlerTask, this));
     }

     // 线程的入口函数
     static void HandlerTask(void* args)
     {
          // 分离线程
          pthread_detach(pthread_self());

          threadpool<T> *tp = static_cast<threadpool<T> *>(args);
          std::string name = tp->GetName(pthread_self());
          while(true)
          {
               //消费任务
               tp->Lock();
               while(tp->IsEmpty())
                    tp->ThreadSleep();
               Task t = tp->Pop();
               tp->UnLock();
               
               //处理任务
               t();
               std::cout << name << "处理任务：" << t.GetTask() << " 结果为：" << t.GetResult() << std::endl;
          }
     }

     void Start()//启动线程池，准备就绪
     {
          for(int i = 0; i < _num; ++i)
               _threads[i].Run();
     }

     // 添加任务(生产任务)，主线程完成
     void Push(const T &task)
     {
          Lock();
          _taskqueue.push(task);
          WaitUp();
          UnLock();
     }
     
     // 处理任务（消费任务），线程池线程完成
     T Pop()
     {
          T t = _taskqueue.front();
          _taskqueue.pop();

          return t;
     }

     ~threadpool()
     {
          pthread_mutex_destroy(&_mutex);
          pthread_cond_destroy(&_cond);
     }
private:
     std::vector<Thread> _threads;       // 线程池
     std::queue<T> _taskqueue;           // 任务队列
     int _num;                           // 线程池的线程数量
     pthread_mutex_t _mutex;             // 维护任务队列的互斥，一次只能一个线程来获取任务
     pthread_cond_t _cond;               // 维护线程的同步，未持有锁的线程在条件变量中阻塞，等待唤醒
};